#include "preHeader.h"
#include "MapServerService.h"
#include "Session/MapServerPacketHandler.h"
#include "Map/InstanceMgr.h"
#include "Object/PlayerMgr.h"
#include "Session/GateServerMgr.h"
#include "Session/GameServerMgr.h"

MapServerService::MapServerService()
: IServerService("MapServerService")
{
}

MapServerService::~MapServerService()
{
}

int MapServerService::HandlePacket(INetPacket& pck)
{
	return sMapServerPacketHandler.HandlePacket(this, pck);
}

void MapServerService::OnRecvPacket(INetPacket* pck)
{
	switch (pck->GetOpcode()) {
	case SMC_TRANS_INSTANCE_PACKET:
		TransInstancePacket(pck);
		break;
	case SMC_TRANS_PLAYER_PACKET:
		TransPlayerPacket(pck);
		break;
	case SMC_TRANS_CLIENT_PACKET:
		TransClientPacket(pck);
		break;
	case SMC_TRANS_GAME_SERVER_PACKET:
		TransGameServerPacket(pck);
		break;
	default:
		IServerService::OnRecvPacket(pck);
		break;
	}
}

void MapServerService::TransInstancePacket(INetPacket *pck) const
{
	InstGUID instGuid;
	*pck >> instGuid;
	MapInstance* pMapInstance = sInstanceMgr.GetMapInstance(instGuid);
	if (pMapInstance != NULL) {
		pMapInstance->PushRecvPacket(
			InstanceService::NewInstancePacket(-1, &pck->UnpackPacket()));
	} else {
		WLOG("Trans instance packet failed, can't find instance [%hu,%hu,%u].",
			instGuid.TID, instGuid.MAPID, instGuid.UID);
		delete pck;
	}
}

void MapServerService::TransPlayerPacket(INetPacket *pck) const
{
	ObjGUID playerGuid;
	*pck >> playerGuid;
	InstGUID instGuid = sPlayerMgr.GetPlayerInstance(playerGuid);
	if (instGuid != InstGUID_NULL) {
		MapInstance* pMapInstance = sInstanceMgr.GetMapInstance(instGuid);
		if (pMapInstance != NULL) {
			pMapInstance->PushRecvPacket(
				InstanceService::NewPlayerPacket(playerGuid, &pck->UnpackPacket()));
		} else {
			WLOG("Trans player packet failed, can't find instance [%hu,%hu,%u].",
				instGuid.TID, instGuid.MAPID, instGuid.UID);
			delete pck;
		}
	} else {
		WLOG("Trans player packet failed, can't find player (%hu,%u).",
			playerGuid.SID, playerGuid.UID);
		delete pck;
	}
}

void MapServerService::TransClientPacket(INetPacket* pck) const
{
	ClientAddr4Cross clientAddr;
	*pck >> clientAddr;
	auto pSession = sGateServerMgr.GetGateServer(clientAddr.guid);
	if (pSession != NULL) {
		pSession->TransPacket(clientAddr.sn, pck->CastReadableStringView());
	} else {
		WLOG("Trans client packet failed, can't find gate server (%u,%u,%u).",
			clientAddr.guid.serverId, clientAddr.guid.gateSN, clientAddr.guid.msSN);
	}
	delete pck;
}

void MapServerService::TransGameServerPacket(INetPacket* pck) const
{
	uint32 gsIdx;
	*pck >> gsIdx;
	if (gsIdx != -1) {
		auto pSession = sGameServerMgr.GetGameServerSession(gsIdx);
		if (pSession != NULL) {
			pSession->PushSendPacket(pck->CastReadableStringView());
		} else {
			WLOG("Trans game server packet failed, can't find server (%u).", gsIdx);
		}
	} else {
		sGameServerMgr.BroadcastPacket2AllGameServer(pck->CastReadableStringView());
	}
	delete pck;
}
